<?
	include_once("cmsConfig.php");
	
	define("CMS_CONTENTBUILDER_BODY_CONTENTBLOCK_CLASS","CmsBodyContentBlock");
	
	class CmsContentBuilder extends CmsKVC    {
		
	
		//this will extend the cmskvc classes..

		//we will have we
		var $contentBlocks;
		var $contentBlockClass = CMS_CONTENTBUILDER_BODY_CONTENTBLOCK_CLASS;

		var $TINYMCE_CSS = TINYMCE_CSS;
		var $TINYMCE_TAGS = TINYMCE_TAGS;
		var $TINYMCE_STYLES =  TINYMCE_STYLES;
		
		function CmsContentBuilder() {
			parent::CmsKVC();

			 $this->keys = array_merge_recursive(	
			 	array(
			 		EXTRACT_TO_MANY_OBJECTS => array(
			 			"contentBlocks"
			 	)),
			 	array(
			 		EXTRACT_TO_ONE_OBJECT => array(
			 	))
			 	,
			 	$this->keys);
			 $this->dataModelKeyMapping = array_merge(
			 	$this->dataModelKeyMapping,
			 	array(
					"contentBlocks" => "extra2",//this is the serialisation/joining of the contentblocks..
			 	)
			 );
			 $this->actions = array_merge_recursive($this->actions, "save", "addContentBlock","deleteContentBlock" );
			 $this->contentBlocks = array();

			 //this will allow us to have custom contentblock classes in other locations.
			 //$this->contentBlockClass = 'CmsBodyContentBlock';
			 
			 // we will also default to no headers/footers.. as at this point in time nothing is using them..
			 //if we are being created.. make a new header and footer??? .. possibly
			 //$this->takeValueForKey( new CmsHeaderContentBlock(),'header');
			 //$this->takeValueForKey( new CmsFooterContentBlock(),'footer');
			 
			 // we will default to no content blocks
			 //we always need at least one cms body content.. no point otherwise..
			 //$this->setContentBlockWithId($cb, $cb->id());
		}

		// we need to get a list of all of the content blocks sorted by position in the newletter.
		function setContentBlockWithId($contentBlock, $id){
			if (is_null($contentBlock) || is_null($id)) return;
			$this->contentBlocks[ $id ] = &$contentBlock;
		}

		function &getContentBlockWithId($id){
			$NULL = null;
			if (key_exists($id, $this->contentBlocks) && !is_null($this->contentBlocks[ $id ]))
				return $this->contentBlocks[ $id ];
			else {
				return $NULL;
			}
		}

		function removeContentBlockWithId($id){
			if(key_exists($id, $this->contentBlocks))  {
				unset($this->contentBlocks[ $id ]);
			}
		}

		function &getAllContentBlocks(){
			return $this->contentBlocks;
		}

		function addContentBlockAction(){
			$newContentBlock = new $this->contentBlockClass();
			$pageOrder = count($this->contentBlocks) + 1;
			$newContentBlock->takeValueForKey( $pageOrder,  'pageOrder');
			//$newContentBlock->takeValueForKey( $this, 'parent' );
			$this->setContentBlockWithId($newContentBlock, $newContentBlock->id());
		}

		function deleteContentBlockAction($contentBlockToDelete){
			//echo "delete";
			//how do we tie these in with a particular instance?..
			if (is_null($contentBlockToDelete) && strlen($contentBlockToDelete) == 8) 
				return;
				
			$this->removeContentBlockWithId($contentBlockToDelete);
		}

// loading and saving the objects
		function save(&$authInfo, &$db ){
			//we need to save all of the children first.. and then the proper one..
			$res = new CmsStatusMessage();//temporary place holder... thing..
			$keys = array_keys($this->contentBlocks);
			foreach ($keys as $key){
				$cb = $this->contentBlocks[ $key ];
				if (!is_null($cb)){
					$cbr = $cb->save($authInfo, $db);

					if ($cbr->hasErrors) {
						$res->hasErrors = true;
						$res->addValidationMessageForKey('contentBlockWithId_'. $cb->valueForKey('id') ,'f_CHILD_OBJEC_FAILED_TO_SAVE',CMS_STATUS_ERROR);
					}
				}
				$this->contentBlocks[ $key ] = $cb;
			}
			//myPrintR($res);
			$r=null;
			if (!$res->hasErrors){
				//echo 'saving self';
				$r = parent::save($authInfo, $db);
				//myPrintR($r);
			}

			//merge
			if (!is_null($r) && $r->hasErrors){
				$r->messages = array_merge($r->messages,$res->messages);
				$r->hasErrors = $r->hasErrors && $res->hasErrors;
				$res = $r;
			}
			return $res;
		}

		function load($id, &$authInfo, &$db){
			$res = parent::load($id, $authInfo, $db);
			if ($res) {
				// now.. this is a little bit of a predicament..
				// how the fuck do we find the content blocks. as we dont have an array..
				// really we need a dictionry of bits and bobs.. or the content actually loaded
				//load the contentblocks..
				$newContentBlocks = array();
				if (!is_array($this->contentBlocks))
					$this->contentBlocks = array();
					
				foreach($this->contentBlocks as $contentBlockId){
					if (is_string($contentBlockId) && strlen($contentBlockId)  == 8 ){
						$cb = new $this->contentBlockClass();
						//echo get_class($cb);
						$cbRes = $cb->load($contentBlockId, $authInfo, $db);
						if (!$cbRes->hasErrors) {
							//$cb->takeValueForKey($this,'parent');//not sure if i am liking this too much .. 
							$newContentBlocks[ $contentBlockId ] = $cb;
						}
					}
				}
				$this->contentBlocks = $newContentBlocks;
			}
			return $res;
		}


		function takeValuesFromRequest() {
			parent::takeValuesFromRequest();
			$keys = array_keys($this->contentBlocks);
			foreach ($keys as $key ){
				$cb = $this->contentBlocks[ $key ];
				$cb->takeValuesFromRequest();
				$this->contentBlocks[$key] = $cb;
			}
		}

		function invokeActions() {
			parent::invokeActions();
			$keys = array_keys($this->contentBlocks);
			foreach ($keys as $key ){
				$cb = $this->contentBlocks[ $key ];
				$cb->invokeActions();
				$this->contentBlocks[$key] = $cb;
			}
		}
		
		function validateContentBlocks() {
			$valid = true;
			if ((count($this->contentBlocks) > 0)) {
				//we need to now invoke the validate methods on
				$keys = array_keys($this->contentBlocks);
				foreach ($keys as $key ){
					$cb = $this->contentBlocks[ $key ];
					$cbv = $cb->validateForSave();
					if (!$cbv) $valid = false;
					$this->contentBlocks[$key] = $cb;
				}
				if (!$valid){
					$valid = VALIDATION_INVALID_CHILDREN;
				}
			}
			//moving the validity check from here to the required field check
			// it will just return not null now... but easier to  
			//else {
			//	return VALIDATION_MORE_THAN_ONE;
			//}
			return $valid;
		}

		function sortContentBlocks() {
			usort($this->contentBlocks, "bodyContentBlockPageOrderSort");
			$pageOrder = 1;
			foreach ($this->contentBlocks as $key => $cb) {
				$cb = $this->contentBlocks[ $key ];
				unset($this->contentBlocks[$key]);//have to rekey here..as usort fucks shit up
				$cb->takeValueForKey($pageOrder, 'pageOrder');
				$this->contentBlocks[$cb->id()] = $cb;
				$pageOrder++;
			}
		}
		
		//this may need factoring back to the base class as a more generic method.
		function saveAction() {//this .. needs to invoke save..
			$valid = $this->validateForSave();
			if ($valid) {
				global $authInfo;
				global $db;
				$res = $this->save($authInfo, $db );

				return true;
			}
			return false;
		}

		function generateForm(&$db){
			//return parent
			return null;
		}

		//serialise the newletter/mailout to html
		function generateHTML(&$db){
			return null;			
		}
		
		
	}
